/*
 * WeightedDistribution.h
 *
 *  Created on: 24.11.2011
 *      Author: jan
 */

#ifndef WEIGHTEDDISTRIBUTION_H_
#define WEIGHTEDDISTRIBUTION_H_

#include "Particle.h"
#include <vector>
#include <cstdlib>

namespace std {
template <class T>
class WeightedDistribution {
public:
	vector<Particle<T> > states;
	double accum;

	WeightedDistribution(vector<Particle<T> > p) : states(),accum(0.0) {
		int n = 0;
		for(unsigned int i = 0; i < p.size(); i++){
			if(p[i].w > 0){
				accum += p[i].w;
				n++;
			}
		}
		double interval = 0;
		double target = 0;
		double uniformWeight = 1.0 / n;
		interval = accum / n;
		double randval = UNIFORM_RAND;
		target = interval * randval;
		accum = 0;
		if( isNotANan(interval)){
			for (unsigned int i = 0; i < p.size(); i++) {
				if (p[i].w > 0) {
					accum += p[i].w;
					while(accum>target){
						p[i].w = uniformWeight;
						this->states.push_back(p[i]);
						target += interval;
					}
				}
			}
		}
	}

	bool isNotANan(double i){
		return (i == i); // nan == nan ist immer false... daher
	}

	~WeightedDistribution() {

	}

	Particle<T> pick(){
		if(states.size() > 0){
			return states[(int)((UNIFORM_RAND_WITHOUT_ONE)*states.size())];
		}
		return Particle<T>(Point(-1,-1));
	}
};

} /* namespace std */
#endif /* WEIGHTEDDISTRIBUTION_H_ */
